package com.wondertek.applet.controller.business;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wondertek.common.base.Result;
import com.wondertek.common.exception.AppException;
import com.wondertek.common.log.AutoLogUtil;
import com.wondertek.service.dto.app.req.AppRoomUpdateModeReq;
import com.wondertek.service.dto.app.req.InstallerPageDeviceReq;
import com.wondertek.service.dto.app.req.InstallerPageRoomReq;
import com.wondertek.service.dto.app.res.*;
import com.wondertek.service.dto.business.req.*;
import com.wondertek.service.dto.business.res.AccessoryPageRes;
import com.wondertek.service.dto.business.res.SiteDeviceAccessoryRes;
import com.wondertek.service.dto.business.res.TimeZoneDictRes;
import com.wondertek.service.dto.sys.req.BaseUpdateReq;
import com.wondertek.service.entity.business.AccessoryPo;
import com.wondertek.service.entity.business.DevicePo;
import com.wondertek.service.entity.business.DeviceTypeDetailPo;
import com.wondertek.service.entity.business.RoomPo;
import com.wondertek.service.sdk.iotdh.dto.req.*;
import com.wondertek.service.sdk.iotdh.dto.req.utc.SetDeviceUTCTimezoneReq;
import com.wondertek.service.sdk.iotdh.dto.res.*;
import com.wondertek.service.sdk.iotdh.dto.res.doorDetector.SetDoorDetectorAccessoryInfoReq;
import com.wondertek.service.sdk.iotdh.dto.res.doorDetectorPlus.SetDoorDetectorPlusAccessoryInfoReq;
import com.wondertek.service.sdk.iotdh.dto.res.network.AroundWirelessNetwork;
import com.wondertek.service.sdk.iotdh.dto.res.network.GetCurrentWirelessNetworkRes;
import com.wondertek.service.sdk.iotdh.dto.res.pir.SetPIRAccessoryInfoReq;
import com.wondertek.service.sdk.iotdh.service.DhDeviceService;
import com.wondertek.service.service.business.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @author wangyu
 */

@RestController
@RequestMapping("/app/business/installer/")
@Tag(name = "installer")
public class InstallerController {

    @Autowired
    private InstallerService installerService;

    @Autowired
    private DeviceService deviceService;

    @Autowired
    private DeviceTypeDetailService deviceTypeService;

    @Autowired
    private AccessoryService accessoryService;

    @Autowired
    private DhDeviceService dhDeviceService;

    @Autowired
    private RoomService roomService;

    @PostMapping("/getUpgradeVersionInfo")
    @Operation(summary = "搜索 Alarm Hub 的云更新版本")
    public Result<GetUpgradeVersionInfoRes> getUpgradeVersionInfo(@RequestBody @Validated ComId req) {
        return dhDeviceService.getUpgradeVersionInfo(req);
    }

    @PostMapping("/upgradeDevice")
    @Operation(summary = "设备升级")
    public Result<?> upgradeDevice(@RequestBody @Validated VerifyDevCodeReq req) {

        if (deviceService.findModeByDeviceSn(req.getDeviceId()) > 0)
            throw new AppException("Some areas are armed, can not operate");

        dhDeviceService.upgradeDevice(req);
        //同时将设备下线下线
        LambdaQueryWrapper<DevicePo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(DevicePo::getSnCode, req.getDeviceId());
        List<DevicePo> list = deviceService.list(lambdaQueryWrapper);
        if (CollectionUtils.isNotEmpty(list)) {
            DevicePo devicePo = list.get(0);
            devicePo.setStatus(0);
            deviceService.updateById(devicePo);
        }
        return Result.success();
    }

    @PostMapping("/getUpgradeProgress")
    @Operation(summary = "搜索Alarm Hub的云更新进度")
    public Result<GetUpgradeProgressRes> getUpgradeProgress(@RequestBody @Validated ComId req) {
        return dhDeviceService.getUpgradeProgress(req);
    }

    @PostMapping("/deviceVersionList")
    @Operation(summary = "获取设备版本和可升级信息")
    public Result<DeviceVersionListRes> deviceVersionList(@RequestBody @Validated DeviceVersionListReq req) {
        return dhDeviceService.deviceVersionList(req);
    }

    @GetMapping("/findAllSiteByUserId")
    @Operation(summary = "根据操作员userid查询所属站点")
    public Result<List<KvRes>> findAllSiteByUserId() {
        return Result.success(installerService.findAllSiteByUserId());
    }

    @PostMapping("/pageDeviceBySiteId")
    @Operation(summary = "根据siteId查询设备")
    public Result<Page<AppDevicePageByUserIdRes>> pageDeviceBySiteId(@RequestBody @Validated InstallerPageDeviceReq req) {
        return Result.success(installerService.pageDeviceBySiteId(req));
    }

    @PostMapping("/pageRoomByDeviceId")
    @Operation(summary = "根据deviceId查询分区")
    public Result<Page<InstallerRoomRes>> pageRoomByDeviceId(@RequestBody @Validated InstallerPageRoomReq req) {
        return Result.success(installerService.pageRoomByDeviceId(req));
    }

    @PostMapping("/addDevice")
    @Operation(summary = "新增设备")
    public Result<?> addDevice(@RequestBody @Validated DeviceAddReq deviceAddReq) {
        deviceService.addDevice(deviceAddReq);
        return Result.success();
    }

    @PostMapping("/addRoom")
    @Operation(summary = "新增房间")
    public Result<?> addRoom(@RequestBody @Validated RoomAddReq adminAddReq) {
        roomService.addRoom(adminAddReq);
        return Result.success();
    }

    @PostMapping("/setAccessoryPair")
    @Operation(summary = "挂载配件")
    public Result setAreaArmMode(@RequestBody @Validated SetAccessoryPairReq req) {
        // accessoryService.setAccessoryPair(req);
        installerService.setAccessoryPair(req);
        return Result.success();
    }

    @PostMapping("/typeSelect")
    @Operation(summary = "查询设备类型")
    public Result<List<DeviceTypeDetailPo>> typeSelect() {
        LambdaQueryWrapper<DeviceTypeDetailPo> wrapper = new LambdaQueryWrapper<>();
        wrapper.apply("category is not null and category!=''");
        return Result.success(deviceTypeService.list(wrapper));
    }

    @PostMapping("/accessoryPage")
    @Operation(summary = "分页查询配件")
    public Result<Page<AccessoryPageRes>> page(@RequestBody AccessoryPageReq req) {
        return Result.success(accessoryService.webPage(req));
    }

    @PostMapping("/network/detail")
    @Operation(summary = "查询网关设备详情")
    public Result<GetStatusRes> networkDetail(@RequestBody @Validated GetStatusReq req) {
        Result<GetStatusRes> res = dhDeviceService.getStatus(req);
        return res;
    }

    @PostMapping("/ipc/detail")
    @Operation(summary = "查询ipc设备详情")
    public Result<String> ipcDetail(@RequestBody @Validated StreamUrlAddDhReq req) {
        return dhDeviceService.addStreamUrl(req);
    }

    @GetMapping("/scan")
    @Operation(summary = "扫码查询设备配件相关信息")
    public Result<InstallerScanRes> scan(@RequestParam("scan") String scan) {
        return Result.success(installerService.scan(scan));
    }

    @PostMapping("/accessoryStatus")
    @Operation(summary = "配件状态查询(前端轮询)")
    public Result<GetAccessoryInfoRes> accessoryStatus(@RequestBody @Validated AccessoryStatusReq req) {
        return Result.success(installerService.accessoryStatus(req));
    }

    @PostMapping("/updateMode")
    @Operation(summary = "更改布防模式")
    public Result<SetAreaArmModeRes> updateMode(@RequestBody @Validated AppRoomUpdateModeReq req) {
        return roomService.updateMode(req);
    }

    @PostMapping("/network/set/detail")
    @Operation(summary = "查询网关设备开关详情")
    public Result<?> setDetail(@RequestBody @Validated GetEnableReq req) {
        return dhDeviceService.getEnable(req);
    }

    @PostMapping("/network/set")
    @Operation(summary = "网关开关设置")
    public Result<?> set(@RequestBody @Validated SetEnableReq req) {
        DevicePo devicePo = new DevicePo();
        devicePo.setSnCode(req.getDeviceId());
        SiteDeviceAccessoryRes res = deviceService.selectSiteDevice(devicePo);
        AutoLogUtil.save("sys", "log.gateway.switch.set", "网关sn码:" + req.getDeviceId(),
                res.getSiteName(), res.getDeviceSn(), res.getSiteId(), null);
        return dhDeviceService.setEnable(req);
    }

    @PostMapping("/accessory/detail")
    @Operation(summary = "配件详情")
    public Result<GetAccessoryInfoRes> detail(@RequestBody @Validated BaseUpdateReq req) {
        return accessoryService.detail(req.getId());
    }

    @PostMapping("/addAccessory")
    @Operation(summary = "新增配件")
    public Result addAccessory(@RequestBody @Validated AccessoryAddReq req) {
        accessoryService.addAccessory(req);
        return Result.success();
    }

    @GetMapping("/findDaTypes")
    @Operation(summary = "查询设备或配件类型")
    public Result<List<DaKvRes>> findDaTypes(@RequestParam("type") Integer type) {
        return Result.success(installerService.findDaTypes(type));
    }

    @PostMapping("/deleteDevice")
    @Operation(summary = "删除设备")
    public Result<?> deleteDevice(@RequestBody @Validated BaseUpdateReq baseUpdateReq) {
        deviceService.deleteDevice(baseUpdateReq.getId());
        return Result.success();
    }

    @PostMapping("/deleteRoom")
    @Operation(summary = "删除房间")
    public Result<?> deleteRoom(@RequestBody @Validated BaseUpdateReq baseUpdateReq) {
        roomService.deleteRoom(baseUpdateReq.getId());
        return Result.success();
    }

    @PostMapping("/delAccessory")
    @Operation(summary = "删除配件")
    public Result delAccessory(@RequestBody DeleteAccessoryReq req) {
        accessoryService.delAccessory(req);
        return Result.success();
    }

    @PostMapping("/setDoorDetectorAccessoryInfo")
    @Operation(summary = "设置⻔磁信息")
    public Result<?> setDoorDetectorAccessoryInfo(@RequestBody @Validated SetDoorDetectorAccessoryInfoReq req) {
        System.out.println("req:" + req);
        //校验分区是否撤防
        this.isArm(req.getAccessoryInfos().get(0).getId());
        AccessoryPo accessoryPo = new AccessoryPo();
        accessoryPo.setAccessoryCode(req.getAccessoryInfos().get(0).getId());
        SiteDeviceAccessoryRes res = deviceService.selectSiteDeviceAccessory(accessoryPo);
        AutoLogUtil.save("sys", "log.door.magnetic.set", "⻔磁sn码:" + res.getAccessorySn(),
                res.getSiteName(), res.getDeviceSn(), res.getSiteId(), res.getAccessorySn());
        accessoryService.setDoorDetectorAccessoryInfo(req);
        return Result.success();
    }

    private void isArm(String accCode) {
        LambdaQueryWrapper<AccessoryPo> accessoryPoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        accessoryPoLambdaQueryWrapper.eq(AccessoryPo::getAccessoryCode, accCode);
        List<AccessoryPo> list = accessoryService.list(accessoryPoLambdaQueryWrapper);
        if (CollectionUtils.isNotEmpty(list)) {
            //根据roomid查布防模式
            AccessoryPo accessory = list.get(0);
            LambdaQueryWrapper<RoomPo> roomPoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            roomPoLambdaQueryWrapper.eq(RoomPo::getId, accessory.getRoomId());
            List<RoomPo> list1 = roomService.list(roomPoLambdaQueryWrapper);
            if (CollectionUtils.isNotEmpty(list1)) {
                RoomPo roomPo = list1.get(0);
                if (!"D".equals(roomPo.getMode())) {
                    throw new AppException("this.room.not.withdraw");
                }
            }
        }
    }

    @PostMapping("/setDoorDetectorPlusAccessoryInfo")
    @Operation(summary = "设置升级⻔磁信息")
    public Result<?> setDoorDetectorPlusAccessoryInfo(@RequestBody @Validated SetDoorDetectorPlusAccessoryInfoReq req) {
        //校验分区是否撤防
        this.isArm(req.getAccessoryInfos().get(0).getId());
        AccessoryPo accessoryPo = new AccessoryPo();
        accessoryPo.setAccessoryCode(req.getAccessoryInfos().get(0).getId());
        SiteDeviceAccessoryRes res = deviceService.selectSiteDeviceAccessory(accessoryPo);
        AutoLogUtil.save("sys", "log.upgrade.door.magnetic.set", "升级⻔磁sn码:" + res.getAccessorySn(),
                res.getSiteName(), res.getDeviceSn(), res.getSiteId(), res.getAccessorySn());
        accessoryService.setDoorDetectorPlusAccessoryInfo(req);
        return Result.success();
    }

    @PostMapping("/setPIRAccessoryInfo")
    @Operation(summary = "设置PIR相机信息")
    public Result<?> setPIRAccessoryInfo(@RequestBody @Validated SetPIRAccessoryInfoReq req) {
        //校验分区是否撤防
        this.isArm(req.getAccessoryInfos().get(0).getId());
        AccessoryPo accessoryPo = new AccessoryPo();
        accessoryPo.setAccessoryCode(req.getAccessoryInfos().get(0).getId());
        SiteDeviceAccessoryRes res = deviceService.selectSiteDeviceAccessory(accessoryPo);
        AutoLogUtil.save("sys", "log.pir.set", "PIR相机sn码:" + res.getAccessorySn(),
                res.getSiteName(), res.getDeviceSn(), res.getSiteId(), res.getAccessorySn());
        accessoryService.setPIRAccessoryInfo(req);
        return Result.success();
    }

    @GetMapping("/deviceRestart")
    @Operation(summary = "设备重启")
    public Result deviceRestart(@RequestParam("deviceSn") String deviceSn) {
        deviceService.deviceRestart(deviceSn);
        return Result.success();
    }

    /**
     * 查询时区字典
     *
     * @return
     */
    @GetMapping("/findTimeZoneDict")
    @Operation(summary = "查询时区字典")
    public Result<List<TimeZoneDictRes>> findTimeZoneDict(String search) {
        return Result.success(deviceService.findTimeZoneDict(search));
    }

    @GetMapping("/findDeviceTimeZone")
    @Operation(summary = "搜索设备时区")
    public Result<TimeZoneDictRes> findDeviceTimeZone(@RequestParam("deviceSn") String deviceSn) {

        return Result.success(deviceService.findDeviceTimeZone(deviceSn));
    }

    /**
     * 设置报警网关所在时区
     *
     * @param req
     */
    @PostMapping("/setDeviceUTCTimezone")
    @Operation(summary = "设置报警网关所在时区")
    public Result setDeviceUTCTimezone(@RequestBody @Validated SetDeviceUTCTimezoneReq req) {
        deviceService.setDeviceUTCTimezone(req);
        return Result.success();
    }

    /**
     * 修改网关设备密码
     *
     * @param req
     */
    @PostMapping("/modifyDevicePassword")
    @Operation(summary = "修改网关设备密码")
    public Result modifyDevicePassword(@RequestBody @Validated ModifyDevicePasswordReq req) {
        deviceService.modifyDevicePassword(req);
        return Result.success();
    }

    @GetMapping("/modifyDevicePasswordCheck")
    @Operation(summary = "点击网关设备密码修改校验")
    public Result modifyDevicePasswordCheck(@RequestParam("deviceSn") String deviceSn) {
        if (deviceService.findModeByDeviceSn(deviceSn) > 0)
            throw new AppException("Some areas are armed, can not operate");

        return Result.success();
    }

    /**
     * 配置有线网络
     *
     * @param networkInfoReq
     */
    @PostMapping("/setNetworkInfo")
    @Operation(summary = "配置有线网络")
    public Result setNetworkInfo(@RequestBody @Validated NetworkInfoReq networkInfoReq) {
        deviceService.setNetworkInfo(networkInfoReq);
        return Result.success();
    }


    /**
     * 查询有线网络
     *
     * @param deviceSn
     * @return
     */
    @GetMapping("/findNetworkInfo")
    @Operation(summary = "查询有线网络")
    public Result<NetworkInfoReq> findNetworkInfo(@RequestParam("deviceSn") String deviceSn) {
        return Result.success(deviceService.findNetworkInfo(deviceSn));
    }

    /**
     * 查询网关正在使用的wifi信息
     *
     * @param deviceSn
     * @return
     */
    @GetMapping("/findUseWifi")
    @Operation(summary = "查询网关正在使用的wifi信息")
    public Result<GetCurrentWirelessNetworkRes> findUseWifi(@RequestParam("deviceSn") String deviceSn) {
        return Result.success(deviceService.findUseWifi(deviceSn));
    }

    /**
     * 查询网关附近的wifi信息
     *
     * @param deviceSn
     * @return
     */
    @GetMapping("/findNearbyWifi")
    @Operation(summary = "查询网关附近的wifi信息")
    public Result<List<AroundWirelessNetwork>> findNearbyWifi(@RequestParam("deviceSn") String deviceSn) {
        return Result.success(deviceService.findNearbyWifi(deviceSn));
    }

    /**
     * 连接wifi
     *
     * @param modifyWirelessNetwork
     */
    @PostMapping("/connectWifi")
    @Operation(summary = "连接wifi")
    public Result connectWifi(@RequestBody @Validated ModifyWirelessNetwork modifyWirelessNetwork) {
        deviceService.connectWifi(modifyWirelessNetwork);
        return Result.success();
    }

    // 设置蜂窝网络
    @GetMapping("/setCellularNetwork")
    @Operation(summary = "设置蜂窝网络")
    public Result setCellularNetwork(@Parameter(name = "deviceSn", required = true, description = "设备sn") @RequestParam("deviceSn") String deviceSn, @Parameter(name = "status", required = true, description = "开启关闭") @RequestParam("status") boolean status) {
        deviceService.setCellularNetwork(deviceSn, status);
        return Result.success();
    }

    // 查询蜂窝网络
    @GetMapping("/findCellularNetwork")
    @Operation(summary = "查询蜂窝网络")
    public Result<Boolean> findCellularNetwork(@Parameter(name = "deviceSn", required = true, description = "设备sn") @RequestParam("deviceSn") String deviceSn) {

        return Result.success(deviceService.findCellularNetwork(deviceSn));
    }


    /**
     * 配件状态检测
     *
     * @param deviceSn
     * @return
     */
    @GetMapping("/findAccessoryStatus")
    @Operation(summary = "配件状态检测")
    public Result<AccessoryStatusDetectionSumReq> findAccessoryStatus(@RequestParam("deviceSn") String deviceSn, @RequestParam("pageNo") Integer pageNo, @RequestParam("pageSize") Integer pageSize) {
        return Result.success(deviceService.findAccessoryStatus(deviceSn, pageNo, pageSize));
    }
}
